/**
 * 在自然界中，人听到的声音受到人与音源间位置、角度变化的影响而有所不同，
 * three.js 提供了 PositionAudio 接口，创建模拟这种自然界听音效果的音频
 * 
 * 下面的代码通过将监听者绑定到相机对象，通过控制相机对象位置，实现听音效果的变化
 */
import * as THREE from '../../build/three.module.js'
import {
  OrbitControls
} from '../../jsm/controls/OrbitControls.js';

const scene = new THREE.Scene();
scene.background = new THREE.Color(0x000000);

const k = innerWidth / innerHeight,
      s = 75,
      camera = new THREE.PerspectiveCamera(s, k, 1, 10000);
camera.position.set(400, 400, 400);
camera.lookAt(scene.position);

// 创建一个定位音频的网格模型
const geo = new THREE.SphereGeometry(10, 20, 20);
const mat = new THREE.MeshPhongMaterial({
  color: 0xefefff,
  side: THREE.DoubleSide
});
const mesh = new THREE.Mesh(geo, mat);
mesh.position.set(0, 0, 0);
scene.add(mesh);

// 光线
let light = new THREE.DirectionalLight(0xefefff, 1.5);
light.position.set(1, 1, 1).normalize();
scene.add(light);
light = new THREE.DirectionalLight(0xefefff, 1.5);
light.position.set(-1, -1, -1).normalize();
scene.add(light);

const axesH = new THREE.AxesHelper(50);
scene.add(axesH);

/**
 * 构建位置音频
 */
const linstener = new THREE.AudioListener();
camera.add(linstener); // 将监听者位置与相机位置绑定

const posAudio = new THREE.PositionalAudio(linstener);
mesh.add(posAudio); // 将位置银屏位置与网格对象绑定

const audioLoader = new THREE.AudioLoader();
audioLoader.load('../../sounds/358232_j_s_song.mp3', ab => {
  posAudio.setBuffer(ab);
  posAudio.setLoop(true);
  posAudio.setVolume(.5);
  posAudio.setRefDistance(200); // 参数越大，声音越大，声音开始衰减的距离
  posAudio.play();
});

const renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(devicePixelRatio);
renderer.setSize(innerWidth, innerHeight);
renderer.gammaOutput = true;
renderer.gammaFactor = 2;
document.body.appendChild(renderer.domElement);

new OrbitControls(camera, renderer.domElement);

(function render() {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
})();